/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.brain.come.mbean;

import com.brain.come.dto.PlanCobroDto;
import com.brain.come.manager.PlanCobroManager;
import com.brain.comp.view.util.ConstantesComp;
import com.brain.conf.dto.MonedaDto;
import com.brain.conf.manager.MonedaManager;
import com.brain.core.common.ExportarExcelCaja;
import com.brain.core.common.ExportarExcelCaja.PlanCobro;
import com.brain.core.common.UtilCore;
import com.brain.core.dto.FechaFiltroDto;
import com.brain.core.dto.ParametroDto;
import com.brain.core.exception.DAOException;
import com.brain.core.manager.RecursosManager;
import com.brain.core.view.mbean.ApplicationMBean;
import com.brain.core.view.mbean.GenericMBean;
import com.brain.core.view.mbean.SessionMBean;
import com.brain.fina.dto.CobroDto;
import com.brain.fina.manager.CobroManager;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import javax.annotation.Resource;
import javax.faces.model.SelectItem;
import org.apache.log4j.Logger;
import org.primefaces.context.RequestContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;

/**
 *
 * @author Hvives
 */

@Controller("planCobroMBean")
@Scope("session")
public class PlanCobroMBean extends GenericMBean implements Serializable{
    
    private static Logger logger = Logger.getLogger(PlanCobroMBean.class);
    
    @Autowired
    private ApplicationMBean applicationMBean;
    
    @Autowired
    private SessionMBean sessionMBean;
    
    @Resource
    private PlanCobroManager manager;
    
    @Resource
    private RecursosManager recursosManager;
    
    @Resource
    private CobroManager managerCobro;
    
    @Resource
    private MonedaManager managerMoneda;
    
    private PlanCobroDto dtoFiltro;
    private FechaFiltroDto dtoFechaFiltro;
    private PlanCobroDto dto;
    private List<PlanCobroDto> lista;
    private String keyTitulo = "";
    private String keyTituloCobro = "";
    private String tituloDetalle;
    private SelectItem[] siEstadosBusqueda;
    private List<ParametroDto> listaFormaPago;
    private List<MonedaDto> listaMonedas;
    private CobroDto cobroDto;
    private List<CobroDto> listaCobros;
    private Date fechaActual;
    private BigDecimal montoConvertido;
    private PlanCobroDto[] selectedPCs;
    private ExportarExcelCaja.PlanCobro pcExcel;
    private String tipoXls;
    private Boolean checkExcel;
    
    public String iniciar(){
        this.lista = null;
        this.dto = null;
        this.cobroDto = null;
        this.dtoFiltro = new PlanCobroDto();
        this.dtoFechaFiltro = new FechaFiltroDto();
        this.dtoFechaFiltro.setFechaInicio(UtilCore.Fecha.agregarDiasFechaDate(UtilCore.Fecha.obtenerFechaActualDate(), applicationMBean.getRangoFechasBusqueda() * -1));
        this.dtoFechaFiltro.setFechaFin(UtilCore.Fecha.obtenerFechaActualDate());
        this.pcExcel = new ExportarExcelCaja.PlanCobro(true);
        this.selectedPCs = null;
        return this.manager.getUrlLista();
    }
    
    public void buscar(){
        try {
            this.lista = this.manager.obtenerDocumentosVentaXPagar(this.dtoFiltro, this.dtoFechaFiltro);
        } catch (DAOException ex) {
            logger.error("ERROR DE SISTEMA", ex);
            showError("Error de Sistema", ex.getMessage());
        }
    }
    
    public String guardar(){        
        if (manager.guardar(this.dto) != null){
            this.editar();
        }
        return null;
    }
    
    public String cobrar(){
        if (manager.cobrar(this.dto) != null){
            this.editar();
        }
        return null;
    }
    
    public String cobrarUbicacion(){
        RequestContext context = RequestContext.getCurrentInstance();
        boolean resultado = true;
        
        this.cobroDto = asignarMontoConvertido(this.cobroDto);
        
        if (this.cobroDto.getFactorConversion() == null){
                recursosManager.showError(UtilCore.Internacionalizacion.getMensajeInternacional("cobro.detalle.no.tipo.cambio"));
                resultado = false;
        }
        else {
            if (validarSumaCobros(this.cobroDto)){
                if (managerCobro.cobrar(this.cobroDto) != null){
                    BigDecimal cobrado = dto.getCobrado().add(cobroDto.getMontoConvertido());
                    dto.setCobrado(cobrado);
                    BigDecimal pendiente = dto.getLiquidar().subtract(cobrado);
                    dto.setPendiente(pendiente);
                    if (dto.getPendiente().equals(BigDecimal.ZERO)){
                        this.manager.cobrar(dto);
                    }
                    else{
                        int index = dto.getListaCobro().indexOf(cobroDto);
                        dto.getListaCobro().set(index, cobroDto);
                        this.manager.cobrarCobro(this.dto);
                    }
                    this.editar();
                }
            }
            else {
                resultado = false;
            }
        }
        context.addCallbackParam("CallbackParam", resultado);
        return null;
    }
    
    public void nuevoDetalle(){
        sessionMBean.setAccionDetalle(applicationMBean.getNuevo());
        this.tituloDetalle = recursosManager.construirTitulo(keyTituloCobro, sessionMBean.getAccionDetalle());
        this.cobroDto = this.managerCobro.inicializar();
        this.cobroDto.setPlanCobroDto(this.dto);
        this.cobroDto.setMonedaDto(this.dto.getMonedaDto());
        this.cobroDto.setFormaPagoDto(this.dto.getFormaPagoDto());
    }
    
    public String retroceder(){
        buscar();
        return manager.getUrlLista();
    }
    
    public String editar(){
        sessionMBean().setAccion(applicationMBean.getEditar());
        sessionMBean().setTitulo(recursosManager.construirTitulo(keyTitulo, sessionMBean().getAccion()));
        try {
            this.listaCobros = managerCobro.obtenerTodosPorId(this.dto);
        } catch (DAOException e) { 
            logger.error(e);
            return null;
        }        
        return manager.getUrl();
    }
    
    public void editarCobro(){
        this.tituloDetalle = recursosManager.construirTitulo(keyTituloCobro, sessionMBean().getAccionDetalle());
        sessionMBean.setAccionDetalle(applicationMBean.getEditar());
        try {
            this.cobroDto = managerCobro.obtenerPorId(this.cobroDto.getId());
        } catch (DAOException ex) {
            logger.error(ex);
        }
    }
    
    public String ver(){
        sessionMBean().setAccion(applicationMBean.getVer());
        sessionMBean().setTitulo(recursosManager.construirTitulo(keyTitulo, sessionMBean().getAccion()));
        return manager.getUrl();
    }
    
    public void verCobro(){
        this.tituloDetalle = recursosManager.construirTitulo(keyTituloCobro, sessionMBean().getAccionDetalle());
        sessionMBean.setAccionDetalle(applicationMBean.getVer());
        try {
            this.cobroDto = managerCobro.obtenerPorId(this.cobroDto.getId());
        } catch (DAOException ex) {
            logger.error(ex);
        }
    }
    
    public void guardarCobroUbicacion() {
        RequestContext context = RequestContext.getCurrentInstance();
        boolean resultado = true;
        try {            
            this.cobroDto = asignarMontoConvertido(this.cobroDto);
            if (this.cobroDto.getFactorConversion() == null){
                recursosManager.showError(UtilCore.Internacionalizacion.getMensajeInternacional("cobro.detalle.no.tipo.cambio"));
                resultado = false;
            }
            else {
                if (validarSumaCobros(this.cobroDto)){                    
                    if (managerCobro.guardar(this.cobroDto) != null) {
                        this.dto = this.manager.obtenerPorId(this.dto.getId());
                    }else{
                        resultado = false;
                    }
                }
                else{
                    resultado = false;
                }
            }                        
        } catch (DAOException ex) {
            showError("ERROR_SISTEMA", ex.getMessage());
            logger.error(ex);
        }
        context.addCallbackParam("CallbackParam", resultado);
    }
    
    public CobroDto asignarMontoConvertido(CobroDto dto){
        CobroDto c = manager.unificarDatosCobroDetalle(dto, this.dto);
        if (c.getFactorConversion() != null){
            c.setMontoConvertido(c.getMonto().multiply(c.getFactorConversion()));
        }
        return c;
    }
    
    public boolean validarSumaCobros(CobroDto cDto){
        String mensajeTrx = "";
        BigDecimal suma = BigDecimal.ZERO;

        for (CobroDto x: this.dto.getListaCobro()){
            if (!x.getId().equals(cDto.getId())){
                suma = suma.add(x.getMontoConvertido());
            }
        }
        if ((suma.add(cDto.getMontoConvertido())).compareTo(this.dto.getLiquidar())==1){
            mensajeTrx = UtilCore.Internacionalizacion.getMensajeInternacional("cobro.mensaje.monto.superado");
            recursosManager.showError(mensajeTrx);
            return false;
        }
        else{            
            return true;
        }
    }
    
    public void eliminarCobro(){
        try {
            this.managerCobro.eliminar(this.cobroDto);
            this.dto = this.manager.obtenerPorId(this.dto.getId());
        } catch (DAOException e) {
            logger.error(e.getMessage());
        }
    }
    
    private void generarExcelSeleccionadosPlanCobro() {
        this.manager.generarExcelSeleccionados(pcExcel, selectedPCs);
    }
    
    private void generarExcelPorTablaPlanCobro() {
        this.manager.generarExcelPorTabla(pcExcel, lista);
    }
    
    public void exportarExcel() {
        if (this.tipoXls.equals("T")) {
            generarExcelPorTablaPlanCobro();
        } else if (this.tipoXls.equals("S")) {
            generarExcelSeleccionadosPlanCobro();
        }
    }
    
    public void cargarPopupExportarExcel(String tipo) {
        RequestContext context = RequestContext.getCurrentInstance();
        boolean resultado = true;
        this.tipoXls = tipo;
        if (tipo.equals("T")) {
            if (lista.isEmpty()) {
                resultado = false;
                this.recursosManager.showWarning(UtilCore.Internacionalizacion.getMensajeInternacional("mensaje.selecc.plan.cobro"));
            }
        } else if (tipo.equals("S")) {

            if (selectedPCs.length <= 0) {
                resultado = false;
                this.recursosManager.showWarning(UtilCore.Internacionalizacion.getMensajeInternacional("mensaje.selecc.plan.cobro"));
            }

        }
        if (resultado) {
            this.pcExcel = new ExportarExcelCaja.PlanCobro(true);
            this.checkExcel = Boolean.TRUE;
        }
        context.addCallbackParam("CallbackParam", resultado);
    }
    
    public void onChangeChekExcel() {
        this.pcExcel = manager.onChangeChekExcel(checkExcel);
    }

    public static Logger getLogger() {
        return logger;
    }

    public static void setLogger(Logger logger) {
        PlanCobroMBean.logger = logger;
    }

    public ApplicationMBean getApplicationMBean() {
        return applicationMBean;
    }

    public void setApplicationMBean(ApplicationMBean applicationMBean) {
        this.applicationMBean = applicationMBean;
    }

    public SessionMBean getSessionMBean() {
        return sessionMBean;
    }

    public void setSessionMBean(SessionMBean sessionMBean) {
        this.sessionMBean = sessionMBean;
    }

    public PlanCobroManager getManager() {
        return manager;
    }

    public void setManager(PlanCobroManager manager) {
        this.manager = manager;
    }

    public RecursosManager getRecursosManager() {
        return recursosManager;
    }

    public void setRecursosManager(RecursosManager recursosManager) {
        this.recursosManager = recursosManager;
    }

    public PlanCobroDto getDtoFiltro() {
        return dtoFiltro;
    }

    public void setDtoFiltro(PlanCobroDto dtoFiltro) {
        this.dtoFiltro = dtoFiltro;
    }

    public FechaFiltroDto getDtoFechaFiltro() {
        return dtoFechaFiltro;
    }

    public void setDtoFechaFiltro(FechaFiltroDto dtoFechaFiltro) {
        this.dtoFechaFiltro = dtoFechaFiltro;
    }

    public PlanCobroDto getDto() {
        return dto;
    }

    public void setDto(PlanCobroDto dto) {
        this.dto = dto;
    }

    public List<PlanCobroDto> getLista() {
        return lista;
    }

    public void setLista(List<PlanCobroDto> lista) {
        this.lista = lista;
    }

    public String getKeyTitulo() {
        return keyTitulo;
    }

    public void setKeyTitulo(String keyTitulo) {
        this.keyTitulo = keyTitulo;
    }

    public SelectItem[] getSiEstadosBusqueda() {
        siEstadosBusqueda = manager.siTiposPlanCobroTodos();
        return siEstadosBusqueda;
    }

    public void setSiEstadosBusqueda(SelectItem[] siEstadosBusqueda) {
        this.siEstadosBusqueda = siEstadosBusqueda;
    }

    public CobroDto getCobroDto() {
        return cobroDto;
    }

    public void setCobroDto(CobroDto cobroDto) {
        this.cobroDto = cobroDto;
    }

    public String getKeyTituloCobro() {
        return keyTituloCobro;
    }

    public void setKeyTituloCobro(String keyTituloCobro) {
        this.keyTituloCobro = keyTituloCobro;
    }

    public CobroManager getManagerCobro() {
        return managerCobro;
    }

    public void setManagerCobro(CobroManager managerCobro) {
        this.managerCobro = managerCobro;
    }

    public String getTituloDetalle() {
        return tituloDetalle;
    }

    public void setTituloDetalle(String tituloDetalle) {
        this.tituloDetalle = tituloDetalle;
    }

    public List<ParametroDto> getListaFormaPago() {
        return this.recursosManager.obtenerParametrosActivosPorCatalogoSistema(ConstantesComp.CatalogoParametro.FORMA_PAGO);
    }

    public void setListaFormaPago(List<ParametroDto> listaFormaPago) {
        this.listaFormaPago = listaFormaPago;
    }

    public List<MonedaDto> getListaMonedas() throws DAOException{
        listaMonedas = managerMoneda.obtenerMonedasActivasPorEmpresa();
        return listaMonedas;
    }

    public void setListaMonedas(List<MonedaDto> listaMonedas) {
        this.listaMonedas = listaMonedas;
    }

    public MonedaManager getManagerMoneda() {
        return managerMoneda;
    }

    public void setManagerMoneda(MonedaManager managerMoneda) {
        this.managerMoneda = managerMoneda;
    }

    public List<CobroDto> getListaCobros() {
        return listaCobros;
    }

    public void setListaCobros(List<CobroDto> listaCobros) {
        this.listaCobros = listaCobros;
    }

    public Date getFechaActual() {
        return UtilCore.Fecha.obtenerFechaActualDate();
    }

    public void setFechaActual(Date fechaActual) {
        this.fechaActual = fechaActual;
    }

    public BigDecimal getMontoConvertido() {
        return montoConvertido;
    }

    public void setMontoConvertido(BigDecimal montoConvertido) {
        this.montoConvertido = montoConvertido;
    }

    public PlanCobroDto[] getSelectedPCs() {
        return selectedPCs;
    }

    public void setSelectedPCs(PlanCobroDto[] selectedPCs) {
        this.selectedPCs = selectedPCs;
    }

    public PlanCobro getPcExcel() {
        return pcExcel;
    }

    public void setPcExcel(PlanCobro pcExcel) {
        this.pcExcel = pcExcel;
    }

    public String getTipoXls() {
        return tipoXls;
    }

    public void setTipoXls(String tipoXls) {
        this.tipoXls = tipoXls;
    }

    public Boolean getCheckExcel() {
        return checkExcel;
    }

    public void setCheckExcel(Boolean checkExcel) {
        this.checkExcel = checkExcel;
    }
}
